﻿using Avalonia.BiliBili.Dialogs;
using Avalonia.BiliBili.Libs.Window;
using Bilibili.Common;
using Bilibili.Model.Resource;
using Bilibili.Model.Video;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;

namespace Avalonia.BiliBili.ViewModels
{
    public sealed class VideoViewModel : ViewModelBase
    {
        public List<PlayerModel> PagerModels { get; }
        public event CallbackDynamicObject VideoViewCallback;
        public ReactiveCommand<string, Unit> OnButtonClick { get; }
        private bool isVideo;
        public bool IsVideo
        {
            get => isVideo;
            set => this.RaiseAndSetIfChanged(ref isVideo, value);
        }
        private bool isPlaying = false;
        public bool IsPlaying
        {
            get => isPlaying;
            set => this.RaiseAndSetIfChanged(ref isPlaying, value);
        }
        private long currentPosition;
        public long CurrentPosition
        {
            get => currentPosition;
            set => this.RaiseAndSetIfChanged(ref currentPosition, value);
        }
        private int currentPage;
        public int CurrentPage
        {
            get => currentPage;
            set => this.RaiseAndSetIfChanged(ref currentPage, value);
        }
        private long maxLength;
        public long MaxLength
        {
            get => maxLength;
            set => this.RaiseAndSetIfChanged(ref maxLength, value);
        }
        private int qnIndex;
        public int QnIndex
        {
            get => qnIndex;
            set
            {
                if (qnIndex != value)
                    VideoViewCallback?.Invoke(this, ("qn", value));
                this.RaiseAndSetIfChanged(ref qnIndex, value);
            }
        }
        private ObservableCollection<QualityInfo> qualityInfos = [];
        public ObservableCollection<QualityInfo> QualityInfos
        {
            get => qualityInfos;
            set => this.RaiseAndSetIfChanged(ref qualityInfos, value);
        }
        public VideoInfoModels VideoInfo { get; internal set; }
        private readonly PlayerWindowBase Owner;
        public VideoViewModel(PlayerWindowBase window)
        {
            Owner = window;
            PagerModels = [];
            OnButtonClick = ReactiveCommand.Create<string>(ButtonClick);
        }
        internal int TakeQn => QualityInfos.ElementAt(QnIndex).Qn;
        private void ButtonClick(string obj)
        {
            RunOnUiThread(async () =>
            {
                switch (obj)
                {
                    case "full":
                    case "next":
                        VideoViewCallback?.Invoke(this, obj);
                        break;
                    case "play":
                    case "pause":
                        IsPlaying = obj.Contains("play", StringComparison.CurrentCultureIgnoreCase);
                        VideoViewCallback?.Invoke(this, obj);
                        break;
                    case "send":
                        VideoViewCallback?.Invoke(this, "pause");
                        var dialog = new DanmakuDialog { Info = (VideoInfo?.Aid, VideoInfo?.Pages.ElementAt(CurrentPage).cid.ToString(), currentPosition) };
                        await dialog.ShowDialog(Owner);
                        VideoViewCallback?.Invoke(this, "play");
                        break;
                }
            });
        }
    }
}